package com.yejiali.backend.filter;

import com.yejiali.backend.common.httpcode.HttpCodeEnum;
import com.yejiali.backend.entity.MyUserDetails;
import com.yejiali.backend.exception.SystemException;
import com.yejiali.backend.utils.JwtTokenUtil;
import com.yejiali.backend.utils.RedisUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Objects;

/**
 * @Author:yejiali
 * @Date:2025/5/11-05-11-14:19
 * @Decsription:com.yejiali.backend.filter
 * @Version:1.0
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        //获取token
        String token = request.getHeader("Authorization");
        //如果token不存在，可能未登录，直接放行
        if(Objects.isNull(token)){
            filterChain.doFilter(request,response);
            return;
        }
        //token存在，需要验证token有效性
        //token 无效
        if(!jwtTokenUtil.validateToken(token)){
            throw new SystemException(HttpCodeEnum.INVALID_TOKEN);
        }
        //获取用户信息
        Claims claims = jwtTokenUtil.extractAllClaims(token);
        String userId =(String) claims.get("userId");
        //从redis中获取userDetails
        MyUserDetails myUserDetails = (MyUserDetails) redisUtil.get("user:" + userId);;
        //如果redis中没有userDetails，用户未登录或已超时
        if(Objects.isNull(myUserDetails)){
            throw new SystemException(HttpCodeEnum.NEED_LOGIN);
        }
        //将用户信息存入SecurityContextHolder中
        Authentication authentication = new UsernamePasswordAuthenticationToken(myUserDetails,null,myUserDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);

        //放行
        filterChain.doFilter(request,response);
    }
}
